<?php
namespace app\admin\controller\yxerp;

use think\facade\Db;
use think\facade\Config;

class Mcp
{
    /**
     * 获取MCP配置
     */
    public function getConfig()
    {
        $config = Db::name('yxerp_mcp_config')->where('id', 1)->find();
        if (!$config) {
            return json(['code' => 0, 'msg' => '配置不存在', 'data' => null]);
        }
        
        // 解密API密钥
        if (!empty($config['api_key'])) {
            $config['api_key'] = $this->decryptApiKey($config['api_key']);
        }
        
        return json(['code' => 1, 'msg' => '获取成功', 'data' => $config]);
    }
    
    /**
     * 保存MCP配置
     */
    public function saveConfig()
    {
        $data = request()->post();
        
        // 加密API密钥
        if (!empty($data['api_key'])) {
            $data['api_key'] = $this->encryptApiKey($data['api_key']);
        }
        
        // 检查配置是否存在
        $exists = Db::name('yxerp_mcp_config')->where('id', 1)->find();
        
        if ($exists) {
            // 更新配置
            $result = Db::name('yxerp_mcp_config')->where('id', 1)->update([
                'enabled' => $data['enabled'] ?? 0,
                'endpoint_url' => $data['endpoint_url'] ?? '',
                'api_key' => $data['api_key'] ?? '',
                'timeout' => $data['timeout'] ?? 30,
                'enabled_tools' => json_encode($data['enabled_tools'] ?? []),
                'mcp_servers' => json_encode($data['mcp_servers'] ?? []),
                'update_time' => date('Y-m-d H:i:s')
            ]);
        } else {
            // 创建配置
            $result = Db::name('yxerp_mcp_config')->insert([
                'id' => 1,
                'enabled' => $data['enabled'] ?? 0,
                'endpoint_url' => $data['endpoint_url'] ?? '',
                'api_key' => $data['api_key'] ?? '',
                'timeout' => $data['timeout'] ?? 30,
                'enabled_tools' => json_encode($data['enabled_tools'] ?? []),
                'mcp_servers' => json_encode($data['mcp_servers'] ?? []),
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ]);
        }
        
        if ($result) {
            return json(['code' => 1, 'msg' => '保存成功']);
        } else {
            return json(['code' => 0, 'msg' => '保存失败']);
        }
    }
    
    /**
     * 调用MCP工具
     */
    public function callTool()
    {
        $data = request()->post();
        $toolName = $data['tool'] ?? '';
        $params = $data['params'] ?? [];
        
        if (empty($toolName)) {
            return json(['code' => 0, 'msg' => '工具名称不能为空']);
        }
        
        try {
            // 根据工具类型调用不同的处理方法
            $result = $this->handleToolCall($toolName, $params);
            return json(['code' => 1, 'msg' => '调用成功', 'data' => $result]);
        } catch (\Exception $e) {
            return json(['code' => 0, 'msg' => '调用失败：' . $e->getMessage()]);
        }
    }
    
    /**
     * 处理工具调用
     */
    private function handleToolCall($toolName, $params)
    {
        switch ($toolName) {
            case 'github':
                return $this->handleGithubTool($params);
            case 'mysql':
                return $this->handleMySQLTool($params);
            case 'web_search':
                return $this->handleWebSearchTool($params);
            default:
                throw new \Exception('不支持的工具类型');
        }
    }
    
    /**
     * 加密API密钥
     */
    private function encryptApiKey($key)
    {
        return openssl_encrypt(
            $key,
            'AES-256-CBC',
            Config::get('app.app_key'),
            0,
            substr(Config::get('app.app_key'), 0, 16)
        );
    }
    
    /**
     * 解密API密钥
     */
    private function decryptApiKey($encrypted)
    {
        return openssl_decrypt(
            $encrypted,
            'AES-256-CBC',
            Config::get('app.app_key'),
            0,
            substr(Config::get('app.app_key'), 0, 16)
        );
    }
    
    /**
     * 处理GitHub工具调用
     */
    private function handleGithubTool($params)
    {
        $config = Db::name('yxerp_mcp_config')->where('id', 1)->find();
        if (!$config || empty($config['api_key'])) {
            throw new \Exception('GitHub配置不存在或API密钥未设置');
        }
        
        $apiKey = $this->decryptApiKey($config['api_key']);
        $action = $params['action'] ?? '';
        
        switch ($action) {
            case 'listRepos':
                return $this->githubListRepos($apiKey, $params);
            case 'createRepo':
                return $this->githubCreateRepo($apiKey, $params);
            case 'createPR':
                return $this->githubCreatePR($apiKey, $params);
            default:
                throw new \Exception('不支持的GitHub操作');
        }
    }
    
    /**
     * 处理MySQL工具调用
     */
    private function handleMySQLTool($params)
    {
        $action = $params['action'] ?? '';
        $sql = $params['sql'] ?? '';
        
        if (empty($sql)) {
            throw new \Exception('SQL语句不能为空');
        }
        
        // 检查SQL安全性
        $this->checkSQLSecurity($sql);
        
        switch ($action) {
            case 'query':
                return Db::query($sql);
            case 'execute':
                return Db::execute($sql);
            default:
                throw new \Exception('不支持的MySQL操作');
        }
    }
    
    /**
     * 处理Web搜索工具调用
     */
    private function handleWebSearchTool($params)
    {
        $query = $params['query'] ?? '';
        if (empty($query)) {
            throw new \Exception('搜索关键词不能为空');
        }
        
        // 这里可以接入第三方搜索API，如Google Custom Search API
        // 目前返回模拟数据
        return [
            'results' => [
                [
                    'title' => '示例搜索结果1',
                    'link' => 'https://example.com/1',
                    'snippet' => '这是一个示例搜索结果的描述...'
                ],
                [
                    'title' => '示例搜索结果2',
                    'link' => 'https://example.com/2',
                    'snippet' => '这是另一个示例搜索结果的描述...'
                ]
            ],
            'total' => 2
        ];
    }
    
    /**
     * 检查SQL安全性
     */
    private function checkSQLSecurity($sql)
    {
        // 禁止危险操作
        $dangerousKeywords = ['DROP', 'DELETE', 'TRUNCATE', 'ALTER', 'UPDATE', 'INSERT'];
        $sql = strtoupper($sql);
        
        foreach ($dangerousKeywords as $keyword) {
            if (strpos($sql, $keyword) !== false) {
                throw new \Exception('SQL语句包含危险操作');
            }
        }
        
        // 可以添加更多安全检查...
    }
    
    /**
     * GitHub - 列出仓库
     */
    private function githubListRepos($apiKey, $params)
    {
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => 'https://api.github.com/user/repos',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                'Authorization: token ' . $apiKey,
                'Accept: application/vnd.github.v3+json',
                'User-Agent: YX-ERP'
            ]
        ]);
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        if ($httpCode !== 200) {
            throw new \Exception('GitHub API调用失败: ' . $response);
        }
        
        return json_decode($response, true);
    }
    
    /**
     * GitHub - 创建仓库
     */
    private function githubCreateRepo($apiKey, $params)
    {
        $name = $params['name'] ?? '';
        if (empty($name)) {
            throw new \Exception('仓库名称不能为空');
        }
        
        $data = [
            'name' => $name,
            'description' => $params['description'] ?? '',
            'private' => $params['private'] ?? false
        ];
        
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => 'https://api.github.com/user/repos',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => [
                'Authorization: token ' . $apiKey,
                'Accept: application/vnd.github.v3+json',
                'User-Agent: YX-ERP'
            ]
        ]);
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        if ($httpCode !== 201) {
            throw new \Exception('创建GitHub仓库失败: ' . $response);
        }
        
        return json_decode($response, true);
    }
    
    /**
     * GitHub - 创建Pull Request
     */
    private function githubCreatePR($apiKey, $params)
    {
        $owner = $params['owner'] ?? '';
        $repo = $params['repo'] ?? '';
        $title = $params['title'] ?? '';
        $head = $params['head'] ?? '';
        $base = $params['base'] ?? 'main';
        
        if (empty($owner) || empty($repo) || empty($title) || empty($head)) {
            throw new \Exception('缺少必要参数');
        }
        
        $data = [
            'title' => $title,
            'head' => $head,
            'base' => $base,
            'body' => $params['body'] ?? ''
        ];
        
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => "https://api.github.com/repos/{$owner}/{$repo}/pulls",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => [
                'Authorization: token ' . $apiKey,
                'Accept: application/vnd.github.v3+json',
                'User-Agent: YX-ERP'
            ]
        ]);
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        if ($httpCode !== 201) {
            throw new \Exception('创建Pull Request失败: ' . $response);
        }
        
        return json_decode($response, true);
    }
    
    /**
     * 记录工具调用日志
     */
    private function logToolCall($toolName, $params, $response, $status = 1, $errorMsg = null)
    {
        try {
            Db::name('yxerp_mcp_logs')->insert([
                'tool_name' => $toolName,
                'params' => json_encode($params),
                'response' => json_encode($response),
                'status' => $status,
                'error_msg' => $errorMsg,
                'create_time' => date('Y-m-d H:i:s')
            ]);
        } catch (\Exception $e) {
            // 日志记录失败不影响主流程
            error_log('记录MCP调用日志失败: ' . $e->getMessage());
        }
    }
} 